package cloudspace.vm.javassist;

import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * The Class MacroDefinition. this class represents a macro definition inside of
 * a javassist configuration file.  See Macro class for more information.
 */
public class MacroDefinition extends Macro
{

	/** The command body. */
	String commandBody;

	/**
	 * Instantiates a new macro definition.
	 * 
	 * @param userMacro
	 *            the user macro
	 * 
	 * @throws MalformedMacroBodyException
	 *             the malformed macro body exception
	 * @throws MalformedMacroNameException
	 *             the malformed macro name exception
	 * @throws MalformedMacroParametersException
	 *             the malformed macro parameters exception
	 */
	public MacroDefinition(String userMacro)
			throws MalformedMacroException
	{
		super(userMacro, "^[a-zA-Z0-9]+\\(", "\\([^\\)]*\\)");
		commandBody = getCommmandBody(macro);
	}

	/**
	 * This method takes a user macro call and tailors the macro definition.
	 * 
	 * @param mCall
	 *            a macro call to define the macro definition.
	 * 
	 * @return the tailored command
	 * 
	 * @throws MacroCallMismatchException
	 *             the macro call mismatch exception
	 */
	public String getTailoredCommand(MacroCall mCall)
			throws MalformedMacroException
	{
		String tailoredBody = commandBody;
		if (macroParams.size() != mCall.getNumberOfParams())
		{
			throw new MalformedMacroException("Macro call to "+mCall.getMacroName()+" has "+mCall.getNumberOfParams()+" and the definition has "+getNumberOfParams());
		}
		Iterator<String> defIter = macroParams.iterator();
		Iterator<String> callIter = mCall.getParameterIterator();

		while (defIter.hasNext() && callIter.hasNext())
		{
			String defParam = defIter.next();
			String callParam = callIter.next();
			tailoredBody = tailoredBody.replaceAll("%\\{\\s*" + defParam
					+ "\\s*\\}", Matcher.quoteReplacement(callParam));
			tailoredBody = tailoredBody.replaceAll("%" + defParam, Matcher
					.quoteReplacement(callParam));

		}
		return tailoredBody;
	}

	private String getCommmandBody(String macro)
			throws MalformedMacroException
	{
		Pattern commands = Pattern.compile("\\\".*\\\"");
		Matcher commandMatcher = commands.matcher(macro);
		String body = "";
		if (commandMatcher.find())
		{
			body = commandMatcher.group();
		}
		else
		{
			throw new MalformedMacroException("Unable to find Macro Body in "+macro);
		}
		body = body.trim().substring(1, body.length() - 1);
		return body;
	}

}
